package tt.dz.service.imp.sys;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import redis.clients.jedis.Jedis;
import tt.dz.dao.ext.system.OmsRoleAuthDao;
import tt.dz.dao.ext.system.OmsRoleDao;
import tt.dz.dao.ext.system.OmsUrlListDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.JsonForList;
import tt.dz.entity.base.OmsCommonParam;
import tt.dz.entity.base.OmsEntityEnum;
import tt.dz.entity.base.OmsSplitratioScheme;
import tt.dz.entity.exception.BizException;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.entity.system.OmsOperList;
import tt.dz.entity.system.OmsRole;
import tt.dz.entity.system.OmsUrlList;
import tt.dz.service.imp.base.BaseService;
import tt.dz.service.sys.RoleService;
import tt.dz.tcp.rpc.ms.SystemMasterServerRpcClient;
import tt.dz.tcp.rpc.ms.client.entity.MasterAddRoleParam;
import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperRoleVO;
import tt.dz.util.Constants;
import tt.dz.util.OmsConstant;
import tt.dz.util.OmsConstant.MsgCodeEnum;
import tt.dz.util.RedisClient;

import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperRoleVO.MasterModifyOperRoleRetVO;

@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class RoleServiceImpl extends BaseService implements RoleService
{
	private Log log = LogFactory.getLog(RoleServiceImpl.class);

	@Autowired
	private OmsRoleDao roleDaoImpl;
	@Autowired
	private OmsRoleAuthDao roleAuthDaoImpl;
	@Value("${masterOmsCode}")
	private String sysCode;

	@Autowired
	private SystemMasterServerRpcClient systemMasterServerRpcClient;

	@Resource
	OmsUrlListDao omsUrlListDao;

	@Override
	public String add(OmsRole role, OmsOperList current_user) throws Exception
	{
		try
		{
			OmsRole roleTmp = new OmsRole();
			roleTmp.setRole_name(role.getRole_name());
			OmsRole roleQury = roleDaoImpl.findOneExample(roleTmp, null, null);
			if (roleQury != null) {
				throw new BizException("Failed to add role to Main Server:角色名称重复");
			}
			
			String currentId = genarateId();
			if (StringUtils.isEmpty(currentId))
				throw new BizException("Failed to generate a new role  id");

			role.setRole_id(currentId);
			if (role != null)
			{
				MasterAddRoleParam masterAddRoleParam = new MasterAddRoleParam();
				masterAddRoleParam.setRoleId(role.getRole_id());
				masterAddRoleParam.setRoleName(role.getRole_name());
				masterAddRoleParam.setCreatedBy(current_user.getMs_manager_id());
				MasterModifyOperRoleRetVO result = systemMasterServerRpcClient.addSysRole(masterAddRoleParam);
				if (result == null || result.getIsSuccess() != OmsConstant.Success)
					throw new BizException("Failed to add role to Main Server");
			}
			role.setValid_flag(1);
			role.setCreate_time(new Date());
			role.setUpdate_time(new Date());
			role.setCreate_oper_id(current_user.getOper_id());
			role.setUpdate_oper_id(current_user.getOper_id());

			roleDaoImpl.add(role);
			return currentId;

		}
		catch (Exception e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	List<String> list = new ArrayList<String>();
	static int flag = 0;

	public void getParentUrlIds(String urlId)
	{
		if (flag == 1 || urlId.equals("0000000000"))
		{
			flag = 0;
			return;
		}
		list.add(urlId);
		OmsUrlList query = new OmsUrlList();
		query.setUrl_id(urlId);
		OmsUrlList url_temp = omsUrlListDao.findOneExample(query, null, null);
		if (url_temp != null && url_temp.getIs_leaf() == 1)
		{
			list.add(url_temp.getUrl_id());
			getParentUrlIds(url_temp.getPre_url_id());
		}
		else
		{
			flag = 1;
		}
		flag = 0;
		return;
	}

	//	for(String temp :url_ids){
	//		getParentUrlIds(temp);
	//		this.list;
	//	}
	@Override
	public JsonCommon<?> addUrlPower(String roleId, String[] urlIds) throws OmsDaoException
	{
		try
		{
			if (StringUtils.isNotEmpty(roleId))
			{
				roleAuthDaoImpl.deleteAuthIds(roleId);
				if (urlIds != null && urlIds.length > 0)
				{
					//从去重角度考虑，后期改写成set
					for (String urlId : urlIds)
					{
						getParentUrlIds(urlId);
					}
					List<String> tempList = new ArrayList<String>();
					for (String i : this.list)
					{
						if (!tempList.contains(i))
						{
							tempList.add(i);
						}
					}
					String[] urlIds_temp = new String[tempList.size()];
					for (int i = 0; i < tempList.size(); i++)
					{
						urlIds_temp[i] = tempList.get(i);
					}

					roleAuthDaoImpl.addOmsRoleAuths(urlIds_temp, roleId);
					list = new ArrayList<String>();

				}
				return OmsConstant.jsonSuccess;
			}
			else
			{
				return OmsConstant.jsonFail;
			}
		}
		catch (Exception e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	@Override
	public JsonCommon<?> update(OmsRole role)
	{
		try
		{   
			OmsRole roleTmp = new OmsRole();
			roleTmp.setRole_name(role.getRole_name());
//			OmsRole roleQury = roleDaoImpl.findOneExample(roleTmp, null, null);
//			if (roleQury != null) {
//				return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "role name can not repeat!");
//			}
			
			//角色名称不能重复
			OmsRole omsRoleTmp = new OmsRole();
		    String condition = " where role_id <>" + role.getRole_id() + " and role_name = '" + role.getRole_name() + "'";
		    List<OmsRole> listOmsRole = roleDaoImpl.findListByCondition(omsRoleTmp, condition);
			if (listOmsRole.size() >0 ) {
				return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "角色名称不能重复!");
			}
			roleDaoImpl.update(role);
			//			//添加关联
			//			if (role.getUrlIds() != null && role.getUrlIds().length  > 0)
			//			{
			////				roleAuthDaoImpl.deleteAuthIds(role.getRole_id());
			////				roleAuthDaoImpl.addOmsRoleAuths(role.getUrlIds(), role.getRole_id());
			//			}
			return this.buildSuccessJsonCommon(role);
		}
		catch (Exception e)
		{
			this.logError("role add error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	@Override
	public JsonCommon<?> delete(String roleId)
	{
		try
		{
			roleDaoImpl.deleteById(roleId, OmsRole.class);
			return this.buildSuccessJsonCommon("success");
		}
		catch (Exception e)
		{
			this.logError("role delete error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	@Override
	public JsonForList<?> findPageOrAll(OmsCommonParam param, OmsRole role)
	{
		try
		{
			List<OmsRole> lst = roleDaoImpl.pagingFind(param, role);
			int total = 0;
			if (param.isQueryTotal())
			{
				total = roleDaoImpl.queryTotalByObject(role);
			}
			return this.buildSuccessJsonForList(param, lst, total);
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	public JsonForList<?> findRolesByEntityType(int entityType)
	{
		try
		{
			Integer[] ets = null;
			if (entityType == OmsEntityEnum.OPERMERCHANT.getValue())
			{
				ets = new Integer[] { OmsEntityEnum.OPERMERCHANT.getValue(), OmsEntityEnum.OPRERMERCHANT_BRANCH.getValue(), OmsEntityEnum.MERCHANT.getValue(), };
			}
			else if (entityType == OmsEntityEnum.FACTORY.getValue())
			{
				ets = new Integer[] { OmsEntityEnum.FACTORY.getValue(), OmsEntityEnum.MERCHANT.getValue(), };
			}
			else
			{
				ets = new Integer[] { OmsEntityEnum.OPERMERCHANT.getValue(), OmsEntityEnum.OPRERMERCHANT_BRANCH.getValue(), OmsEntityEnum.MERCHANT.getValue(), OmsEntityEnum.FACTORY.getValue() };
			}
			return this.buildSuccessJsonForList(roleDaoImpl.findRolesByEntityType(ets));
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	/**
	 * 生成Role_id
	 *
	 * @return
	 */
	private String genarateId()
	{
		String roleIdKey = "idSequence:RoleId";
		/*ValueOperations<String, String> ops = redis.opsForValue();
		String roleValue = ops.get(roleIdKey);*/
		String roleValue = RedisClient.get(roleIdKey);
		StringBuilder roleId = new StringBuilder();
		roleId.append(sysCode);
		String maxId = roleValue;
		//		redis.multi();
		try
		{
			if (StringUtils.isEmpty(roleValue))
			{
				maxId = this.roleDaoImpl.findMaxPkIdBySingle(Constants.PkLength.ROLE_ID_AUTO_INRC_LENGTH, OmsRole.class);
				//ops.set(roleIdKey, maxId);
				RedisClient.putString(roleIdKey, maxId);
			}
			//ops.increment(roleIdKey, 1l);
//			RedisClient.getConnect().incrBy(roleIdKey, 1l);
			Jedis jedis = RedisClient.getConnect();
			jedis.incrBy(roleIdKey, 1l);
			jedis.close();
			maxId = this.genarateId(maxId, Constants.PkLength.ROLE_ID_AUTO_INRC_LENGTH);
		}
		catch (OmsDaoException e)
		{
			this.logError(e.getMessage(), e);
			//			redis.discard();
			return null;
		}
		roleId.append(maxId);
		//		redis.exec();
		return roleId.toString();
	}

	//查询用户已经绑定的角色
	@Override
	public JsonForList<?> findExistRolesByOperId(String operId)
	{
		return roleDaoImpl.findExistRolesByOperId(operId);
	}

	//查询用户尚未绑定（按用户实体类型和实体ID可以绑定）的角色
	@Override
	public JsonForList<?> findCanbindRolesByOperId(String operId, String entityId, String entityType)
	{
		return roleDaoImpl.findCanbindRolesByOperId(operId, entityId, entityType);
	}

}
